# -- coding: utf-8 --
class Dog(object):
    """docstring for Dog"""
    def __init__(self, name, age):
        super(Dog, self).__init__()
        self.name = name
        self.age = age

    def sit(self):
        print(self.name.title() + ' is now sitting')

    def roll_over(self):
        print(self.name.title() + ' is ' + str(self.age) + ' age old and now rolling')


## 根据约定，在 Python 中，首字母大写的 名称指的是类。
## __init__() 是一个特殊的方法，每当创建新实例时，Python 都会自动运行它。
## 在这个方法的定义中，形参 self 必不可少，还必须位于其他形参的前面。
## 为何必须在方法定义中包 含形参 self 呢?
## 因为Python调用这个__init__() 方法来创建类的实例时，将自动传入实参 self 。
## 每个与类相关联的方法调用都自动传递实参 self ，它是一个指向实例本身 的引用，让实例能够访问类中的属性和方法。


## 下面创建一个特定小狗的实例
my_dog = Dog('Willy', 6)
print(my_dog.name)
print(my_dog.age)
my_dog.sit()
my_dog.roll_over()
## 说明
## 在这里，命名约定很有用：我们通常可以认为首字母大写的名称(如 Dog )指的是类，而 小写的名称(如 my_dog )指的是根据类创建的实例。
## 要访问实例的属性，用句点号关联实例与其属性即可，如 my_dog.name
## 要访问实例的方法，也是用据点好关联实例与方法，如 my_dog.sit()



## 下面创建一个类和实例，并通过多种方法修改实例的属性
## 需求：创建一个汽车实例，汽车的属性有厂商、型号、年代，需要建立实例的时候传入参数
## 然后用展示了 3 种方式如何修改实例的属性
class Car():
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year
        # 下面给汽车的 km 属性指定一个默认值
        self.km = 0

    ## 需求：建立一个方法，返回汽车的信息
    def get_des_name(self):
        long_name = str(self.year) + ' ' + self.make + ' ' + self.model
        return long_name.title()

    ## 需求：建立一个方法，读出汽车的里程值
    def read_km(self):
        print('This car has ran ' + str(self.km) + ' kilometers yet.')

    ## 需求：建立一个方法，输入新的里程值，然后修改汽车的里程值
    def update_km(self, km):
        if km <= self.km:
            print('new km should bigger than the old one')
        else:
            self.km = km

    ## 需求，建立一个方法，输入一个递增数值，每次调用，自动递增汽车的里程值
    def auto_increment(self, km):
        if km <= 0:
            print('The number should be a positive number')
        else:
            self.km += km

bmw = Car('BMW', 'X5', 2008)
print(bmw.get_des_name())
# 下面直接读出当前汽车的默认里程值
bmw.read_km()
# 方式一：下面直接修改汽车的里程值，然后读出
bmw.km = 50
bmw.read_km()
# 方式二：下面通过修改汽车里程值的方法，修改汽车的里程值
bmw.update_km(20)
bmw.read_km()
# 方式三：下面通过递增数值，显示每跑一次后，汽车的里程值
bmw.auto_increment(5)
bmw.read_km()
bmw.auto_increment(100)
bmw.read_km()
bmw.auto_increment(100)
bmw.read_km()
